package com.cddx.logistics.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.cddx.logistics.domain.dto.TransferPageDTO;
import com.cddx.logistics.domain.pojo.TransferRecord;
import com.cddx.logistics.domain.vo.MaterialInfoVO;
import com.cddx.logistics.domain.vo.TransferQueryVO;
import com.cddx.logistics.domain.vo.TransferRecordVO;
import com.cddx.logistics.mapper.*;
import com.cddx.logistics.service.TransferService;
import com.cddx.logistics.util.model.R;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class TransferServiceImpl implements TransferService {
    @Resource
    private TransferMapper transferMapper;
    @Resource
    private InventoryMapper inventoryMapper;
    @Resource
    private MaterialMapper materialMapper;
    @Resource
    private StorageLocationMapper storageLocationMapper;
    @Override
    public R transferList(TransferPageDTO transferPageDTO) {
        PageHelper.startPage(transferPageDTO.getPage(), transferPageDTO.getLimit());
        List<TransferQueryVO> transferQueryList = transferMapper.transferList(transferPageDTO);
        List<TransferRecordVO> voList=transferQueryList.stream().map(transferQueryVO -> {
            TransferRecordVO vo= BeanUtil.copyProperties(transferQueryVO,TransferRecordVO.class);
            vo.setLocationPreName(transferQueryVO.getWarehousePreName()+"-"+transferQueryVO.getLocationPreName());
            vo.setLocationAfterName(transferQueryVO.getWarehouseAfterName()+"-"+transferQueryVO.getLocationAfterName());
            return vo;
        }).collect(Collectors.toList()); ;
        PageInfo<TransferRecordVO> pageInfo = new PageInfo<>(voList);
        return R.ok(pageInfo);
    }

    @Override
    public R deleteTransfer(List<Integer> ids) {
        return transferMapper.deleteTransfer(ids)?R.ok("删除成功"):R.error("删除失败");
    }

    @Override
    public R deleteTransfer(Integer id) {
        return transferMapper.deleteById(id)?R.ok("删除成功"):R.error("删除失败");
    }

    @Override
    @Transactional
    public R addTransfer(TransferRecord transferRecord) {
        //判断库存是否合规
        Float  quantity = transferRecord.getQuantity();
        Float preQuantity= inventoryMapper.getQuantity(
                transferRecord.getLocationPreId(),
                transferRecord.getMaterialId()
        );
        if(preQuantity<quantity){
            return R.error("转移数量不能大于转移前的库存数量!");
        }
//获取物料重量及体积信息
        MaterialInfoVO materialInfoVO = materialMapper.getMaterialInfo(transferRecord.getMaterialId());
        if(inventoryMapper.checkExists(transferRecord.getMaterialId(), transferRecord.getLocationAfterId())){

            return transferMapper.insert(transferRecord)&&inventoryMapper.transferUpdate(
                    transferRecord.getMaterialId(),
                    transferRecord.getLocationPreId(),
                    transferRecord.getLocationAfterId(),
                    quantity,quantity*materialInfoVO.getWeight(),quantity*materialInfoVO.getVolume()
            ) ?R.ok(transferRecord):R.error("添加失败");
        }
        else {
            return transferMapper.insert(transferRecord)&&inventoryMapper.insert(
                    transferRecord.getMaterialId(),
                    storageLocationMapper.getWarehouseId(transferRecord.getLocationAfterId()),
                    transferRecord.getLocationAfterId(),
                    UUID.randomUUID().toString(),
                    transferRecord.getQuantity(),
                    materialInfoVO.getUnit(),
                    quantity*materialInfoVO.getWeight(),
                    quantity*materialInfoVO.getVolume()
            )?R.ok(transferRecord):R.error("添加失败");
        }


    }

    @Override
    @Transactional
    public R update(TransferRecord transferRecord) {
        Integer id = transferRecord.getId();
        TransferRecord pre=transferMapper.getById(id);
        //先将旧数据还原再更新新数
        //获取先前的物料重量及体积信息
        MaterialInfoVO preMaterialInfoVO = materialMapper.getMaterialInfo(pre.getMaterialId());
        //回退库存变化
        inventoryMapper.transferUpdate(
                pre.getMaterialId(),
                pre.getLocationAfterId(),
                pre.getLocationPreId(),
                pre.getQuantity(),
                pre.getQuantity()*preMaterialInfoVO.getWeight(),
                pre.getQuantity()*preMaterialInfoVO.getVolume()
        );
        //判断数量是否合规
        Float  quantity = transferRecord.getQuantity();
        Float preQuantity= inventoryMapper.getQuantity(
                transferRecord.getLocationPreId(),
                transferRecord.getMaterialId()
        );
        if(preQuantity<quantity){
            return R.error("转移数量不能大于转移前的库存数量!");
        }
        //获取新的物料重量及体积信息
        MaterialInfoVO afterMaterialInfoVO = materialMapper.getMaterialInfo(transferRecord.getMaterialId());
        //更新移动记录以及库存信息
        return transferMapper.update(transferRecord)&&
                inventoryMapper.transferUpdate(
                        transferRecord.getMaterialId(),
                        transferRecord.getLocationPreId(),
                        transferRecord.getLocationAfterId(),
                        transferRecord.getQuantity(),
                        quantity*afterMaterialInfoVO.getWeight(),
                        quantity*afterMaterialInfoVO.getVolume()
                )
                ?R.ok("修改成功"):R.error("修改失败");
    }

    @Override
    public R getTransferWarehouses() {
        return R.ok(transferMapper.getTransferWarehouses());
    }

    @Override
    public R getTransferLocation(Long warehouseId) {
        return R.ok(storageLocationMapper.listStorageLocationsByWarehouse(warehouseId));
    }

    @Override
    public R getTransferAddLocation() {
        return R.ok(storageLocationMapper.listAllStorageLocations2Warehouse());
    }

}
